﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using EFong.Data;
using EFong.BL.Const;
using System.Xml.Linq;
using System.Xml;

namespace EFong.BL
{
    public class BaseBL
    {
        #region Static Data

        private EFongEntities entities = EFongEntitiesManager.GetInstance();

        private static List<Contract.Currency> _currencyList;
        public static List<Contract.Currency> CurrencyList
        {
            get
            {
                {
                    if (_currencyList == null)
                    {
                        EFongEntities entities = EFongEntitiesManager.GetInstance();

                        _currencyList = (from c in entities.Currency
                                         select new Contract.Currency()
                                         {
                                             ID = c.ID,
                                             Name = c.Name.Trim(),
                                             Code = c.Code.Trim(),
                                             ExchangeRate = (from er in entities.ExchangeRate
                                                             where er.SourceCurrencyID.Equals(c.ID)
                                                             select er.Rate).FirstOrDefault()
                                         }).ToList();
                    }

                    return _currencyList;
                }
            }
        }

        private static List<Contract.AuthorizedItem> _authorizedItemList;
        public static List<Contract.AuthorizedItem> AuthorizedItemList
        {
            get
            {
                lock (syncObject)
                {
                    if (_authorizedItemList == null)
                    {
                        EFongEntities entities = EFongEntitiesManager.GetInstance();

                        _authorizedItemList = (from h in entities.AuthorizedItem
                                               select new Contract.AuthorizedItem()
                                               {
                                                   ID = h.ID,
                                                   Name = h.Name.Trim(),
                                               }).ToList();
                    }

                    return _authorizedItemList;
                }
            }
        }

        private static List<Contract.HotelLevel> _hotelLevelList;
        public static List<Contract.HotelLevel> HotelLevelList
        {
            get
            {
                lock (syncObject)
                {
                    if (_hotelLevelList == null)
                    {
                        EFongEntities entities = EFongEntitiesManager.GetInstance();

                        _hotelLevelList = (from h in entities.HotelLevel
                                           select new Contract.HotelLevel()
                                           {
                                               ID = h.ID,
                                               Name = h.Name.Trim(),
                                           }).ToList();
                    }

                    return _hotelLevelList;
                }
            }
        }

        private static List<Contract.Role> _roleList = null;
        public static List<Contract.Role> RoleList
        {
            get
            {
                lock (syncObject)
                {
                    if (_roleList == null)
                    {
                        EFongEntities entities = EFongEntitiesManager.GetInstance();

                        _roleList = (from r in entities.Role
                                     select new Contract.Role()
                                     {
                                         ID = r.ID,
                                         Name = r.Name.Trim(),
                                         Effective = r.Effective,

                                     }).ToList();

                        foreach (Contract.Role role in _roleList)
                        {
                            role.Authorities = (from ra in entities.RoleAuthorize
                                                where ra.RoleID == role.ID
                                                select new Contract.RoleAuthorizedItem()
                                                {
                                                    AuthorizedItem = (from ai in entities.AuthorizedItem
                                                                      where ai.ID == ra.ItemID
                                                                      select new Contract.AuthorizedItem()
                                                                      {
                                                                          ID = ai.ID,
                                                                          Name = ai.Name.Trim()
                                                                      }).FirstOrDefault(),
                                                    Allow = ra.Allow
                                                }).ToList();
                        }
                    }

                    return _roleList;
                }
            }
        }

        private static List<Contract.User> _userList = null;
        public static List<Contract.User> UserList
        {
            get
            {
                lock (syncObject)
                {
                    if (_userList == null)
                    {
                        EFongEntities entities = EFongEntitiesManager.GetInstance();

                        _userList = (from u in entities.User
                                     select new Contract.User()
                                     {
                                         ID = u.ID,
                                         Name = u.Name.Trim(),
                                         Password = u.Password.Trim(),
                                         Staff = u.Staff.Trim(),
                                         Effective = u.Effective,
                                         EntryDate = u.EntryDate,
                                         LeaveDate = u.LeaveDate,
                                         Role = new Contract.Role() { ID = u.RoleID }
                                     }).ToList();

                        foreach (Contract.User user in _userList)
                        {
                            user.Role = RoleList.Find(r => r.ID == user.Role.ID);
                        }
                    }

                    return _userList;
                }
            }
        }

        private List<Contract.CustomerHotelIntergralRate> originalHotelIntergralRateList = null;
        public List<Contract.CustomerHotelIntergralRate> OriginalHotelIntergralRateList
        {
            get
            {
                lock (syncObject)
                {
                    if (originalHotelIntergralRateList == null)
                    {

                        originalHotelIntergralRateList = new List<Contract.CustomerHotelIntergralRate>();
                        foreach (Contract.HotelLevel hotelLevel in GetAllHotelLevel())
                        {
                            Contract.CustomerHotelIntergralRate customerHotelIntergralRate = new Contract.CustomerHotelIntergralRate();
                            customerHotelIntergralRate.HotelLevel = hotelLevel;
                            customerHotelIntergralRate.Intergral = 0;

                            originalHotelIntergralRateList.Add(customerHotelIntergralRate);
                        }
                    }

                    return originalHotelIntergralRateList;
                }
            }
        }


        private static object syncObject = new object();
        private static object syncNr = new object();

        #endregion

        #region Method

        public List<Contract.Currency> GetAllCurrency()
        {
            return CurrencyList;
        }

        public Contract.Currency GetCNYCurrency()
        {
            return (from c in CurrencyList
                    where c.Code == "CNY"
                    select c).Single();
        }

        public Contract.Currency GetCurrencyByID(int id)
        {
            return (from c in CurrencyList
                    where c.ID == id
                    select c).Single();
        }

        public void UpdateExchangeRate(List<Contract.Currency> currencyList)
        {
            lock (CurrencyList)
            {
                Contract.Currency cnyCurrency = GetCNYCurrency();


                entities.ExchangeRate.Delete(a => 1 == 1);

                foreach (Contract.Currency currency in currencyList)
                {
                    if (currency.Code.Equals(cnyCurrency.Code))
                        continue;
                    if (currency.ExchangeRate == null)
                        continue;

                    ExchangeRate exchangeRate = new ExchangeRate();
                    exchangeRate.ID = Guid.NewGuid();
                    exchangeRate.SourceCurrencyID = currency.ID;
                    exchangeRate.TargetCurrencyID = cnyCurrency.ID;
                    exchangeRate.Rate = currency.ExchangeRate.Value;

                    entities.AddToExchangeRate(exchangeRate);
                }

                entities.SaveChanges();
            }
        }

        private void testUpdateExchangeRate()
        {
            List<Contract.Currency> curtrencyList = new List<Contract.Currency>() 
            { 
                new Contract.Currency()
                {
                    ID = 2,
                    Code = "HKD",
                    ExchangeRate = 0.87m                    
                },
                new Contract.Currency()
                {
                    ID = 3,
                    Code = "USD",
                    ExchangeRate = 7.3m                    
                }
            };

            UpdateExchangeRate(curtrencyList);
        }

        public Contract.User Login(string name, string password)
        {

            User user = (from u in entities.User
                         where u.Name == name
                         select u).SingleOrDefault();
            if (user == null)
                throw new BusinessException(CommonFail.用户不存在);
            if (user.Password.Trim() != password.Trim())
                throw new BusinessException(CommonFail.密码不正确);
            if (!user.Effective)
                throw new BusinessException(CommonFail.该用户已被停用);

            return new Contract.User()
            {
                ID = user.ID,
                Name = user.Name,
                Staff = user.Staff,
                Role = getRole(user.RoleID)
            };
        }

        public List<Contract.User> GetAllUser()
        {
            return UserList;
        }

        public List<Contract.User> GetEffUser()
        {
            return (from u in UserList
                    where u.Effective
                    select u).ToList();
        }

        public Contract.User GetUserByID(Guid id)
        {

            Contract.User user = (from u in entities.User
                                  where u.ID == id
                                  select new Contract.User()
                                  {
                                      ID = u.ID,
                                      Name = u.Name.Trim(),
                                      Staff = u.Staff.Trim(),
                                      Role = new Contract.Role()
                                      {
                                          ID = u.RoleID
                                      }
                                  }).SingleOrDefault();
            user.Role = getRole(user.Role.ID);

            return user;
        }

        public void NewUser(Contract.User user)
        {

            User oldUser = (from u in entities.User
                            where u.Name == user.Name
                            select u).SingleOrDefault();
            if (oldUser != null)
                throw new BusinessException(CommonFail.该用户已存在);

            checkUser(user);

            User newUser = new User()
            {
                ID = user.ID,
                Name = user.Name,
                Password = user.Password,
                Staff = user.Staff,
                RoleID = user.Role.ID,
                Effective = user.Effective,
            };

            entities.AddToUser(newUser);
            entities.SaveChanges();
        }

        private void checkUser(Contract.User user)
        {
            user.Name = user.Name.Trim();
            user.Password = user.Password.Trim();
            user.Staff = user.Staff.Trim();
            if (user.Name == string.Empty)
                throw new BusinessException(VerificationText.请输入账号);
            if (user.Password == string.Empty)
                throw new BusinessException(VerificationText.请输入密码);
            if (user.Staff == string.Empty)
                throw new BusinessException(VerificationText.请输入员工名);
            if (user.Role == null)
                throw new BusinessException(VerificationText.请输入角色);
        }

        public void ModifyUserPassword(string userName, string oldPassword, string newPassword)
        {
            User user = (from u in entities.User
                         where u.Name == userName
                         select u).SingleOrDefault();
            if (user == null)
                throw new BusinessException(CommonFail.用户不存在);
            if (user.Password.Trim() != oldPassword.Trim())
                throw new BusinessException(CommonFail.密码不正确);
            if (!user.Effective)
                throw new BusinessException(CommonFail.该用户已被停用);

            user.Password = newPassword.Trim();

            entities.SaveChanges();
        }

        public void UpdateUserList(List<Contract.User> userList)
        {

            foreach (Contract.User user in userList)
            {
                checkUser(user);

                User oldUser = (from u in entities.User
                                where u.ID == user.ID
                                select u).SingleOrDefault();
                if (oldUser == null)
                {
                    User newUser = new User()
                    {
                        ID = user.ID,
                        Name = user.Name,
                        Password = user.Password,
                        Staff = user.Staff,
                        RoleID = user.Role.ID,
                        EntryDate = user.EntryDate,
                        LeaveDate = user.LeaveDate,
                        Effective = user.Effective,
                    };

                    entities.AddToUser(newUser);
                }
                else
                {
                    oldUser.Password = user.Password;
                    oldUser.Staff = user.Staff;
                    oldUser.EntryDate = user.EntryDate;
                    oldUser.LeaveDate = user.LeaveDate;
                    oldUser.RoleID = user.Role.ID;
                    oldUser.Effective = user.Effective;
                }
            }

            entities.SaveChanges();

            _userList = null;
        }

        public List<Contract.Role> GetAllRole()
        {
            return RoleList;
        }

        public void NewRole(Contract.Role role)
        {
            checkRole(role);


            Role oldRole = (from r in entities.Role
                            where r.Name == role.Name
                            select r).SingleOrDefault();
            if (oldRole != null)
                throw new BusinessException(CommonFail.该角色已存在);

            Role newRole = new Role()
            {
                ID = role.ID,
                Name = role.Name,
                Effective = role.Effective,
            };
            entities.AddToRole(newRole);

            foreach (Contract.RoleAuthorizedItem roleAuthorizedItem in role.Authorities)
            {
                RoleAuthorize roleAuthorize = new RoleAuthorize();
                roleAuthorize.ID = Guid.NewGuid();
                roleAuthorize.ItemID = roleAuthorizedItem.AuthorizedItem.ID;
                roleAuthorize.RoleID = newRole.ID;
                roleAuthorize.Allow = roleAuthorizedItem.Allow;

                entities.AddToRoleAuthorize(roleAuthorize);
            }

            entities.SaveChanges();
        }

        private void checkRole(Contract.Role role)
        {
            role.Name = role.Name.Trim();
            if (role.Name == string.Empty)
                throw new BusinessException(VerificationText.请输入角色名);
        }

        public void UpdateRoleList(List<Contract.Role> roleList)
        {


            foreach (Contract.Role role in roleList)
            {
                checkRole(role);

                Role oldRole = (from r in entities.Role
                                where r.Name == role.Name
                                select r).SingleOrDefault();
                if (oldRole == null)
                {
                    Role newRole = new Role()
            {
                ID = role.ID,
                Name = role.Name,
                Effective = role.Effective,
            };
                    entities.AddToRole(newRole);

                    foreach (Contract.RoleAuthorizedItem roleAuthorizedItem in role.Authorities)
                    {
                        RoleAuthorize roleAuthorize = new RoleAuthorize();
                        roleAuthorize.ID = Guid.NewGuid();
                        roleAuthorize.ItemID = roleAuthorizedItem.AuthorizedItem.ID;
                        roleAuthorize.RoleID = newRole.ID;
                        roleAuthorize.Allow = roleAuthorizedItem.Allow;

                        entities.AddToRoleAuthorize(roleAuthorize);
                    }
                }
                else
                {
                    oldRole.Effective = role.Effective;

                    entities.RoleAuthorize.Delete(ra => ra.RoleID == role.ID);

                    foreach (Contract.RoleAuthorizedItem roleAuthorizedItem in role.Authorities)
                    {
                        RoleAuthorize roleAuthorize = new RoleAuthorize();
                        roleAuthorize.ID = Guid.NewGuid();
                        roleAuthorize.ItemID = roleAuthorizedItem.AuthorizedItem.ID;
                        roleAuthorize.RoleID = oldRole.ID;
                        roleAuthorize.Allow = roleAuthorizedItem.Allow;

                        entities.AddToRoleAuthorize(roleAuthorize);
                    }
                }
            }

            _roleList = null;

            entities.SaveChanges();
        }

        private Contract.Role getRole(Guid id)
        {
            Contract.Role role = RoleList.Find(r => r.ID == id);


            //Contract.Role role = (from r in entities.Role
            //                      where r.ID == id
            //                      select new Contract.Role()
            //                      {
            //                          ID = r.ID,
            //                          Name = r.Name.Trim(),
            //                          Effective = r.Effective,
            //                          Authorities = (from ra in entities.RoleAuthorize
            //                                         where ra.RoleID == r.ID
            //                                         select new Contract.RoleAuthorizedItem()
            //                                         {
            //                                             AuthorizedItem = (from ai in entities.AuthorizedItem
            //                                                               where ai.ID == ra.ItemID
            //                                                               select new Contract.AuthorizedItem()
            //                                                               {
            //                                                                   ID = ai.ID,
            //                                                                   Name = ai.Name.Trim()
            //                                                               }).FirstOrDefault(),
            //                                             Allow = ra.Allow
            //                                         }).ToList()
            //                      }).SingleOrDefault();
            if (role != null && (!role.Effective))
                throw new BusinessException(CommonFail.该用户所属角色已停用);

            return role;
        }

        public string GetNewNr(string type)
        {
            lock (syncNr)
            {

                Nr nr = (from n in entities.Nr
                         where n.Name == type
                         select n).Single();
                int newNr = nr.NextNr;
                nr.NextNr++;
                entities.SaveChanges();

                return string.Format("{0}{1}", nr.Code.Trim(), buildNumberCode(newNr, nr.Length));
            }
        }

        private string buildNumberCode(int nr, int length)
        {
            string nrString = nr.ToString();
            if (nrString.Length >= length)
                return nrString;
            int oldLength = nrString.Length;
            for (int i = 0; i < length - oldLength; i++)
                nrString = "0" + nrString;

            return nrString;
        }

        private string testGetNewNr()
        {
            return GetNewNr("Customer");
        }

        public List<Contract.HotelLevel> GetAllHotelLevel()
        {
            return HotelLevelList;
        }

        public List<Contract.AuthorizedItem> GetAllAuthorizedItem()
        {
            return AuthorizedItemList;
        }

        public List<Contract.CustomerHotelIntergralRate> GetOriginalHotelIntergralRateList()
        {
            return OriginalHotelIntergralRateList;
        }

        public List<Contract.WebUser> GetAvailableWebUserList()
        {
            return (from wu in entities.WebUser
                    where (from c in entities.Customer
                           where c.WebUserID == wu.ID
                           select c).Count() == 0
                    select new Contract.WebUser()
                    {
                        ID = wu.ID,
                        Name = wu.Name,
                    }).ToList();
        }

        public DateTime GetDate()
        {
            return DateTime.Now;
        }

        private string md5(string text)
        {
            System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] by = md5.ComputeHash(Encoding.UTF8.GetBytes(text));
            StringBuilder sb = new StringBuilder();
            foreach (byte b in by)
                sb.Append(convertTo16(b));
            return sb.ToString();
        }

        private string convertTo16(byte b)
        {
            int high, low;
            high = Math.DivRem(Convert.ToInt32(b), 16, out low);
            return convertTo16(high) + convertTo16(low);
        }

        private string convertTo16(int b)
        {
            switch (b)
            {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                    return b.ToString();
                case 10:
                    return "A";
                case 11:
                    return "B";
                case 12:
                    return "C";
                case 13:
                    return "D";
                case 14:
                    return "E";
                case 15:
                    return "F";
                default:
                    return string.Empty;
            }
        }

        public void ImportData(XElement data)
        {
            foreach (XElement detail in data.Elements())
            {
                switch (detail.Name.LocalName)
                {
                    case "WebUser":
                        XElement id = (from x in detail.Elements()
                                       where x.Name.LocalName == "ID"
                                       select x).SingleOrDefault();
                        XElement name = (from x in detail.Elements()
                                         where x.Name.LocalName == "Name"
                                         select x).SingleOrDefault();
                        WebUser webUser = (from wu in entities.WebUser
                                           where wu.ID == new Guid(id.Value)
                                           select wu).SingleOrDefault();
                        if (webUser == null)
                        {
                            webUser = (from wu in entities.WebUser
                                       where wu.Name == name.Value
                                       select wu).SingleOrDefault();
                            if (webUser == null)
                            {
                                webUser = new WebUser();
                                entities.AddToWebUser(webUser);
                                webUser.ID = new Guid(id.Value);
                                webUser.Name = name.Value;
                                webUser.Password = string.Empty;
                                webUser.CreateTime = new DateTime(2000, 1, 1);
                                webUser.UpdateTime = new DateTime(2000, 1, 1);
                                webUser.CreateParty = "网站";
                            }
                        }
                        break;
                    case "CustomerSettlement":
                        XElement sourceID = (from x in detail.Elements()
                                             where x.Name.LocalName == "SourceID"
                                             select x).SingleOrDefault();
                        CustomerSettlement customerSettlement = (from cs in entities.CustomerSettlement
                                                                 where cs.SourceID == new Guid(sourceID.Value)
                                                                 select cs).SingleOrDefault();
                        if (customerSettlement == null)
                        {
                            customerSettlement = new CustomerSettlement();
                            customerSettlement.ID = new Guid((from x in detail.Elements()
                                                              where x.Name.LocalName == "ID"
                                                              select x).SingleOrDefault().Value);
                            customerSettlement.CustomerID = new Guid((from x in detail.Elements()
                                                                      where x.Name.LocalName == "CustomerID"
                                                                      select x).SingleOrDefault().Value);
                            customerSettlement.SourceID = new Guid(sourceID.Value);
                            customerSettlement.Type = (from x in detail.Elements()
                                                       where x.Name.LocalName == "Type"
                                                       select x).SingleOrDefault().Value;
                            customerSettlement.SettlementDate = Convert.ToDateTime((from x in detail.Elements()
                                                                                    where x.Name.LocalName == "SettlementDate"
                                                                                    select x).SingleOrDefault().Value);
                            customerSettlement.Amount = Convert.ToDecimal((from x in detail.Elements()
                                                                           where x.Name.LocalName == "Amount"
                                                                           select x).SingleOrDefault().Value);
                            customerSettlement.Intergral = 0;
                            customerSettlement.CheckNo = string.Empty;
                            customerSettlement.Remark = string.Empty;
                            customerSettlement.Ref = (from x in detail.Elements()
                                                      where x.Name.LocalName == "Ref"
                                                      select x).SingleOrDefault().Value;
                            customerSettlement.PayType = (from x in detail.Elements()
                                                          where x.Name.LocalName == "PayType"
                                                          select x).SingleOrDefault().Value;
                            customerSettlement.CreateTime = new DateTime(2000, 1, 1);
                            customerSettlement.CreateParty = "网站";

                            entities.AddToCustomerSettlement(customerSettlement);

                            switch (customerSettlement.Type.Trim())
                            { 
                                case "飞机票":
                                    FlightOrder flightOrder = (from fo in entities.FlightOrder
                                                               where fo.ID == customerSettlement.SourceID
                                                               select fo).SingleOrDefault();
                                    flightOrder.CustomerStatus = "已收款";
                                    break;
                                case "飞机票改票":
                                    FlightChange flightChange = (from fo in entities.FlightChange
                                                               where fo.ID == customerSettlement.SourceID
                                                               select fo).SingleOrDefault();
                                    flightChange.CustomerStatus = "已收款";
                                    break;
                                case "飞机票退票":
                                    FlightReturn flightReturn = (from fo in entities.FlightReturn
                                                               where fo.ID == customerSettlement.SourceID
                                                               select fo).SingleOrDefault();
                                    flightReturn.CustomerStatus = "已收款";
                                    break;
                                case "火车票":
                                    TrainTicketOrder trainTicketOrder = (from fo in entities.TrainTicketOrder
                                                               where fo.ID == customerSettlement.SourceID
                                                               select fo).SingleOrDefault();
                                    trainTicketOrder.CustomerStatus = "已收款";
                                    break;
                                case "火车票退票":
                                    TrainTicketReturn trainTicketReturn = (from fo in entities.TrainTicketReturn
                                                               where fo.ID == customerSettlement.SourceID
                                                               select fo).SingleOrDefault();
                                    trainTicketReturn.CustomerStatus = "已收款";
                                    break;
                                case "酒店":
                                    HotelBooking hotelBooking = (from fo in entities.HotelBooking
                                                               where fo.ID == customerSettlement.SourceID
                                                               select fo).SingleOrDefault();
                                    hotelBooking.CustomerStatus = "已收款";
                                    break;
                                case "其他":
                                    OtherBusiness otherBusiness = (from fo in entities.OtherBusiness
                                                               where fo.ID == customerSettlement.SourceID
                                                               select fo).SingleOrDefault();
                                    otherBusiness.CustomerStatus = "已收款";
                                    break;
                                case "自组团":
                                    TouringParty touringParty = (from fo in entities.TouringParty
                                                               where fo.ID == customerSettlement.SourceID
                                                               select fo).SingleOrDefault();
                                    touringParty.CustomerStatus = "已收款";
                                    break;
                            }
                        }
                        break;
                }
            }

            entities.SaveChanges();
        }

        public XElement ExportData(DateTime dateTime)
        {
            XElement exportData = new XElement("Data");

            var customerDataList = from c in entities.Customer
                                   where c.UpdateTime > dateTime
                                   select c;
            foreach (var c in customerDataList)
                exportData.Add(new XElement("Customer",
                                  new XElement("ID", c.ID),
                                  new XElement("Nr", c.Nr.Trim()),
                                  new XElement("Name", c.Name.Trim()),
                                  new XElement("Intergral", c.Intergral),
                                  new XElement("WebUserID", c.WebUserID),
                                  new XElement("CreateTime", c.CreateTime),
                                  new XElement("UpdateTime", c.UpdateTime)));

            var webUserDataList = from wb in entities.WebUser
                                  where wb.CreateTime > dateTime && wb.CreateParty == "程序"
                                  select wb;
            foreach (var webUser in webUserDataList)
                exportData.Add(new XElement("WebUser",
                                  new XElement("ID", webUser.ID),
                                  new XElement("Name", webUser.Name.Trim()),
                                  new XElement("Password", md5(webUser.Password.Trim())),
                                  new XElement("CreateTime", webUser.CreateTime),
                                  new XElement("UpdateTime", webUser.UpdateTime)));

            var flightOrderDataList = from wb in entities.FlightOrder
                                      where wb.UpdateTime > dateTime
                                      select wb;
            foreach (var flightOrder in flightOrderDataList)
                exportData.Add(new XElement("FloghtOrder",
                                  new XElement("ID", flightOrder.ID),
                                  new XElement("Ref", flightOrder.Ref.Trim()),
                                  new XElement("CustomerID", flightOrder.CustomerID),
                                  new XElement("CreditTerm", flightOrder.CreditTerm.Trim()),
                                  new XElement("OrderDate", flightOrder.OrderDate),
                                  new XElement("TotalAccountReceivable", flightOrder.TotalAccountReceivable),
                                  new XElement("IsInternational", flightOrder.IsInternational),
                                  new XElement("Status", flightOrder.Status.Trim()),
                                  new XElement("CustomerStatus", flightOrder.CustomerStatus.Trim()),
                                  new XElement("TotalIntergral", flightOrder.TotalIntergral),
                                  new XElement("CreateTime", flightOrder.CreateTime),
                                  new XElement("UpdateTime", flightOrder.UpdateTime)));

            var flightOrderDetailDataList = from wb in entities.FlightOrderDetail
                                            where wb.UpdateTime > dateTime
                                            select wb;
            foreach (var flightOrderDetail in flightOrderDetailDataList)
                exportData.Add(new XElement("FlightOrderDetail",
                                  new XElement("ID", flightOrderDetail.ID),
                                  new XElement("FlightOrderID", flightOrderDetail.FlightOrderID),
                                  new XElement("Passenger", flightOrderDetail.Passenger.CName.Trim() != string.Empty ? flightOrderDetail.Passenger.CName.Trim() : flightOrderDetail.Passenger.EName.Trim()),
                                  new XElement("Price", flightOrderDetail.Price),
                                  new XElement("Tax1", flightOrderDetail.Tax1),
                                  new XElement("Tax2", flightOrderDetail.Tax2),
                                  new XElement("InsurancePolicy", getInsurancePolicyText(flightOrderDetail)),
                                  new XElement("IsInsurancePolicyFree", flightOrderDetail.IsInsurancePolicyFree),
                                  new XElement("VendorDiscount", flightOrderDetail.VendorDiscount),
                                  new XElement("Cost", flightOrderDetail.Cost),
                                  new XElement("NetPrice", flightOrderDetail.NetPrice),
                                  new XElement("AccountReceivable", flightOrderDetail.AccountReceivable),
                                  new XElement("JourneyOrder", getJourneyOrderText(flightOrderDetail)),
                                  new XElement("TicketNo", flightOrderDetail.TicketNo.Trim()),
                                  new XElement("Status", flightOrderDetail.Status.Trim()),
                                  new XElement("Intergral", flightOrderDetail.Intergral),
                                  new XElement("CreateTime", flightOrderDetail.CreateTime),
                                  new XElement("UpdateTime", flightOrderDetail.UpdateTime)));

            var flightWayDataList = from wb in entities.FlightWay
                                    where wb.UpdateTime > dateTime
                                    select wb;
            foreach (var flightWay in flightWayDataList)
                exportData.Add(new XElement("FlightWay",
                                  new XElement("ID", flightWay.ID),
                                  new XElement("FlightOrderDetailID", flightWay.FlightOrderDetailID),
                                  new XElement("DepartDate", flightWay.DepartDate),
                                  new XElement("DepartLocation", flightWay.DepartLocation.Trim()),
                                  new XElement("Destination", flightWay.Destination.Trim()),
                                  new XElement("FlightNo", flightWay.FlightNo.Trim()),
                                  new XElement("Seat", flightWay.Seat.Trim()),
                                  new XElement("IsDelete", flightWay.IsDelete),
                                  new XElement("CreateTime", flightWay.CreateTime),
                                  new XElement("UpdateTime", flightWay.UpdateTime)));

            var flightChangeDataList = from wb in entities.FlightChange
                                       where wb.UpdateTime > dateTime
                                       select wb;
            foreach (var flightChange in flightChangeDataList)
                exportData.Add(new XElement("FlightChange",
                                  new XElement("ID", flightChange.ID),
                                  new XElement("FlightOrderDetailID", flightChange.FlightOrderDetailID),
                                  new XElement("Ref", flightChange.Ref.Trim()),
                                  new XElement("Price", flightChange.Price),
                                  new XElement("OrderDate", flightChange.OrderDate),
                                  new XElement("CustomerStatus", flightChange.CustomerStatus.Trim()),
                                  new XElement("CreateTime", flightChange.CreateTime),
                                  new XElement("UpdateTime", flightChange.UpdateTime)));

            var flightReturnDataList = from wb in entities.FlightReturn
                                       where wb.UpdateTime > dateTime
                                       select wb;
            foreach (var flightReturn in flightReturnDataList)
                exportData.Add(new XElement("FlightReturn",
                                  new XElement("ID", flightReturn.ID),
                                  new XElement("FlightOrderDetailID", flightReturn.FlightOrderDetailID),
                                  new XElement("Ref", flightReturn.Ref.Trim()),
                                  new XElement("CustomerReturnPrice", flightReturn.CustomerReturnPrice),
                                  new XElement("CustomerReturnAmount", flightReturn.CustomerReturnAmount),
                                  new XElement("OrderDate", flightReturn.OrderDate),
                                  new XElement("CustomerStatus", flightReturn.CustomerStatus.Trim()),
                                  new XElement("CreateTime", flightReturn.CreateTime),
                                  new XElement("UpdateTime", flightReturn.UpdateTime),
                                  new XElement("Intergral", flightReturn.Intergral)));

            var trainTicketOrderDataList = from wb in entities.TrainTicketOrder
                                           where wb.UpdateTime > dateTime
                                           select wb;
            foreach (var trainTicketOrder in trainTicketOrderDataList)
                exportData.Add(new XElement("TrainTicketOrder",
                                  new XElement("ID", trainTicketOrder.ID),
                                  new XElement("CustomerID", trainTicketOrder.CustomerID),
                                  new XElement("Ref", trainTicketOrder.Ref.Trim()),
                                  new XElement("CreditTerm", trainTicketOrder.CreditTerm.Trim()),
                                  new XElement("ProvideTicketDate", trainTicketOrder.ProvideTicketDate),
                                  new XElement("OrderDate", trainTicketOrder.OrderDate),
                                  new XElement("TotalPrice", trainTicketOrder.TotalPrice),
                                  new XElement("TicketTotalQty", trainTicketOrder.TicketTotalQty),
                                  new XElement("Status", trainTicketOrder.Status.Trim()),
                                  new XElement("CustomerStatus", trainTicketOrder.CustomerStatus.Trim()),
                                  new XElement("CreateTime", trainTicketOrder.CreateTime),
                                  new XElement("UpdateTime", trainTicketOrder.UpdateTime)));

            var trainTicketOrderDetailDataList = from wb in entities.TrainTicketOrderDetail
                                                 where wb.UpdateTime > dateTime
                                                 select wb;
            foreach (var trainTicketOrderDetail in trainTicketOrderDetailDataList)
                exportData.Add(new XElement("TrainTicketOrderDetail",
                                  new XElement("ID", trainTicketOrderDetail.ID),
                                  new XElement("TrainTicketOrderID", trainTicketOrderDetail.TrainTicketOrderID),
                                  new XElement("DepartDate", trainTicketOrderDetail.DepartDate),
                                  new XElement("DepartLocation", trainTicketOrderDetail.DepartLocation.Trim()),
                                  new XElement("Destination", trainTicketOrderDetail.Destination.Trim()),
                                  new XElement("TrainNo", trainTicketOrderDetail.TrainNo.Trim()),
                                  new XElement("SeatType", trainTicketOrderDetail.SeatType.Trim()),
                                  new XElement("TicketPrice", trainTicketOrderDetail.TicketPrice),
                                  new XElement("DeliveryCost", trainTicketOrderDetail.DeliveryCost),
                                  new XElement("Qty", trainTicketOrderDetail.Qty),
                                  new XElement("TotalPrice", trainTicketOrderDetail.TotalPrice),
                                  new XElement("Status", trainTicketOrderDetail.Status.Trim()),
                                  new XElement("CreateTime", trainTicketOrderDetail.CreateTime),
                                  new XElement("UpdateTime", trainTicketOrderDetail.UpdateTime)));

            var trainTicketReturnDataList = from wb in entities.TrainTicketReturn
                                            where wb.UpdateTime > dateTime
                                            select wb;
            foreach (var trainTicketReturn in trainTicketReturnDataList)
                exportData.Add(new XElement("TrainTicketReturn",
                                  new XElement("ID", trainTicketReturn.ID),
                                  new XElement("TrainTicketOrderID", trainTicketReturn.Ref.Trim()),
                                  new XElement("TrainTicketOrderDetailID", trainTicketReturn.TrainTicketOrderDetailID),
                                  new XElement("Qty", trainTicketReturn.Qty),
                                  new XElement("OrderDate", trainTicketReturn.OrderDate),
                                  new XElement("CustomerStatus", trainTicketReturn.CustomerStatus.Trim()),
                                  new XElement("CustomerReturn", trainTicketReturn.CustomerReturn),
                                  new XElement("CreateTime", trainTicketReturn.CreateTime),
                                  new XElement("UpdateTime", trainTicketReturn.UpdateTime)));

            var hotelBookingDataList = from wb in entities.HotelBooking
                                       where wb.UpdateTime > dateTime
                                       select wb;
            foreach (var hotelBooking in hotelBookingDataList)
                exportData.Add(new XElement("HotelBooking",
                                  new XElement("ID", hotelBooking.ID),
                                  new XElement("TrainTicketOrderID", hotelBooking.Ref.Trim()),
                                  new XElement("CustomerID", hotelBooking.CustomerID),
                                  new XElement("Ref", hotelBooking.Ref.Trim()),
                                  new XElement("PaymentType", hotelBooking.PaymentType.Trim()),
                                  new XElement("RoomTotalQty", hotelBooking.RoomTotalQty),
                                  new XElement("OrderDate", hotelBooking.OrderDate),
                                  new XElement("TotalPrice", hotelBooking.TotalPrice),
                                  new XElement("Status", hotelBooking.Status.Trim()),
                                  new XElement("CustomerStatus", hotelBooking.CustomerStatus.Trim()),
                                  new XElement("CreateTime", hotelBooking.CreateTime),
                                  new XElement("UpdateTime", hotelBooking.UpdateTime),
                                  new XElement("Intergral", hotelBooking.Intergral)));

            var hotelBookingDetailDataList = from wb in entities.HotelBookingDetail
                                             where wb.UpdateTime > dateTime
                                             select wb;
            foreach (var hotelBookingDetail in hotelBookingDetailDataList)
                exportData.Add(new XElement("HotelBookingDetail",
                                  new XElement("ID", hotelBookingDetail.ID),
                                  new XElement("HotelBookingID", hotelBookingDetail.HotelBookingID),
                                  new XElement("HotelName", hotelBookingDetail.HotelName.Trim()),
                                  new XElement("HotelLevel", hotelBookingDetail.HotelLevel.Trim()),
                                  new XElement("GuestName", hotelBookingDetail.GuestName.Trim()),
                                  new XElement("CheckInDate", hotelBookingDetail.CheckInDate),
                                  new XElement("CheckOutDate", hotelBookingDetail.CheckOutDate),
                                  new XElement("Days", hotelBookingDetail.Days),
                                  new XElement("RoomType", hotelBookingDetail.RoomType.Trim()),
                                  new XElement("Rooms", hotelBookingDetail.Rooms),
                                  new XElement("Price", hotelBookingDetail.Price),
                                  new XElement("TotalPrice", hotelBookingDetail.TotalPrice),
                                  new XElement("Intergral", hotelBookingDetail.Intergral),
                                  new XElement("CreateTime", hotelBookingDetail.CreateTime),
                                  new XElement("UpdateTime", hotelBookingDetail.UpdateTime)));

            var otherBusinessDataList = from wb in entities.OtherBusiness
                                        where wb.UpdateTime > dateTime
                                        select wb;
            foreach (var otherBusiness in otherBusinessDataList)
                exportData.Add(new XElement("OtherBusiness",
                                  new XElement("ID", otherBusiness.ID),
                                  new XElement("CustomerID", otherBusiness.CustomerID),
                                  new XElement("Ref", otherBusiness.Ref.Trim()),
                                  new XElement("Project", otherBusiness.Project.Name.Trim()),
                                  new XElement("SubProject", otherBusiness.SubProject != null ? otherBusiness.SubProject.Name.Trim() : string.Empty),
                                  new XElement("Contenct", otherBusiness.Contenct.Trim()),
                                  new XElement("CustomerName", otherBusiness.CustomerName.Trim()),
                                  new XElement("OrderDate", otherBusiness.OrderDate),
                                  new XElement("ProjectDate", otherBusiness.ProjectDate),
                                  new XElement("Price", otherBusiness.Price),
                                  new XElement("Qty", otherBusiness.Qty),
                                  new XElement("Intergral", otherBusiness.Intergral),
                                  new XElement("TotalPrice", otherBusiness.TotalPrice),
                                  new XElement("Intergral", otherBusiness.Intergral),
                                  new XElement("Status", otherBusiness.Status.Trim()),
                                  new XElement("CustomerStatus", otherBusiness.CustomerStatus.Trim()),
                                  new XElement("CreateTime", otherBusiness.CreateTime),
                                  new XElement("UpdateTime", otherBusiness.UpdateTime)));

            var touringPartyDataList = from wb in entities.TouringParty
                                       where wb.Status != "草拟" &&
                                             wb.UpdateTime > dateTime
                                       select wb;
            foreach (var touringParty in touringPartyDataList)
                exportData.Add(new XElement("TouringParty",
                                  new XElement("ID", touringParty.ID),
                                  new XElement("CustomerID", touringParty.CustomerID),
                                  new XElement("Ref", touringParty.Ref.Trim()),
                                  new XElement("Name", touringParty.Name.Trim()),
                                  new XElement("AdultQty", touringParty.AdultQty),
                                  new XElement("ChildQty", touringParty.ChildQty),
                                  new XElement("TotalPrice", touringParty.TotalPrice),
                                  new XElement("AverageChildPrice", touringParty.TotalPrice),
                                  new XElement("AverageAdultPrice", touringParty.TotalPrice),
                                  new XElement("CustomerStatus", touringParty.CustomerStatus.Trim()),
                                  new XElement("OrderDate", touringParty.OrderDate),
                                  new XElement("IsShowOnWeb", touringParty.IsShowOnWeb),
                                  new XElement("CreateTime", touringParty.CreateTime),
                                  new XElement("UpdateTime", touringParty.UpdateTime)));

            var touringPartyItemDataList = from wb in entities.TouringPartyItem
                                           join tp in entities.TouringParty on wb.TouringPartyID equals tp.ID
                                           where tp.Status != "草拟" &&
                                                 wb.UpdateTime > dateTime
                                           select wb;
            foreach (var touringPartyItem in touringPartyItemDataList)
                exportData.Add(new XElement("TouringPartyItem",
                                  new XElement("ID", touringPartyItem.ID),
                                  new XElement("TouringPartyID", touringPartyItem.TouringPartyID),
                                  new XElement("Type", touringPartyItem.Type.Trim()),
                                  new XElement("Name", touringPartyItem.Name.Trim()),
                                  new XElement("Price", touringPartyItem.Price),
                                  new XElement("Qty", touringPartyItem.Qty),
                                  new XElement("UM", touringPartyItem.UM.Trim()),
                                  new XElement("CalcType", touringPartyItem.CalcType),
                                  new XElement("TotalPrice", touringPartyItem.TotalPrice),
                                  new XElement("Seq", touringPartyItem.Seq),
                                  new XElement("CreateTime", touringPartyItem.CreateTime),
                                  new XElement("UpdateTime", touringPartyItem.UpdateTime)));

            var intergralExchangeDataList = from wb in entities.IntergralExchange
                                            where wb.UpdateTime > dateTime
                                            select wb;
            foreach (var intergralExchange in intergralExchangeDataList)
                exportData.Add(new XElement("IntergralExchange",
                                  new XElement("ID", intergralExchange.ID),
                                  new XElement("CustomerID", intergralExchange.CustomerID),
                                  new XElement("Date", intergralExchange.Date),
                                  new XElement("Item", intergralExchange.Item.Trim()),
                                  new XElement("Qty", intergralExchange.Qty),
                                  new XElement("Amount", intergralExchange.Amount),
                                  new XElement("Receiptor", intergralExchange.Receiptor.Trim()),
                                  new XElement("CreateTime", intergralExchange.CreateTime),
                                  new XElement("UpdateTime", intergralExchange.UpdateTime)));

            var customerSettlementDataList = from wb in entities.CustomerSettlement
                                             where wb.CreateTime > dateTime && wb.CreateParty == "程序"
                                             select wb;
            foreach (var customerSettlement in customerSettlementDataList)
                exportData.Add(new XElement("CustomerSettlement",
                                  new XElement("ID", customerSettlement.ID),
                                  new XElement("CustomerID", customerSettlement.CustomerID),
                                  new XElement("SourceID", customerSettlement.SourceID),
                                  new XElement("Type", customerSettlement.Type.Trim()),
                                  new XElement("SettlementDate", customerSettlement.SettlementDate),
                                  new XElement("Amount", customerSettlement.Amount),
                                  new XElement("Intergral", customerSettlement.Intergral),
                                  new XElement("CheckNo", customerSettlement.CheckNo.Trim()),
                                  new XElement("Remark", customerSettlement.Remark.Trim()),
                                  new XElement("Ref", customerSettlement.Ref.Trim()),
                                  new XElement("PayType", customerSettlement.PayType.Trim()),
                                  new XElement("CreateTime", customerSettlement.CreateTime)));

            var latestExportDate = (from sd in entities.SystemData
                                    where sd.Name == "LatestExportDate"
                                    select sd).SingleOrDefault();
            if (latestExportDate == null)
            {
                latestExportDate = new SystemData();
                latestExportDate.Name = "LatestExportDate";
                entities.AddToSystemData(latestExportDate);
            }
            latestExportDate.Value = DateTime.Now.ToString();

            entities.SaveChanges();

            XmlTextWriter w = new XmlTextWriter(Console.Out);
            w.Formatting = Formatting.Indented;
            exportData.WriteTo(w);
            w.Close();

            return exportData;
        }

        private string getInsurancePolicyText(FlightOrderDetail flightOrderDetail)
        {
            StringBuilder sb = new StringBuilder();
            bool isFirst = true;
            foreach (InsurancePolicy insurancePolicy in flightOrderDetail.InsurancePolicy)
            {
                if (!isFirst)
                    sb.Append(" / ");
                sb.Append(insurancePolicy.Ref.Trim());
            }

            return sb.ToString();
        }

        private string getJourneyOrderText(FlightOrderDetail flightOrderDetail)
        {
            StringBuilder sb = new StringBuilder();
            bool isFirst = true;
            foreach (JourneyOrder journeyOrder in flightOrderDetail.JourneyOrder)
            {
                if (!isFirst)
                    sb.Append(" / ");
                sb.Append(journeyOrder.Ref.Trim());
            }

            return sb.ToString();
        }

        private void test()
        {
            ExportData(DateTime.Now.AddDays(-1));
        }

        public DateTime GetLatestExportDate()
        {
            var latestExportDate = (from sd in entities.SystemData
                                    where sd.Name == "LatestExportDate"
                                    select sd.Value).SingleOrDefault();
            if (latestExportDate == null)
                return new DateTime(2000, 1, 1);
            else
                return Convert.ToDateTime(latestExportDate);

        }

        #endregion
    }
}
